#include "Thread.h"

#define THREAD_CANCELADO 0

using namespace TP::Threading;

Thread::Thread() {
	this->trabajando = false;
}

Thread::~Thread() { }

void Thread::Iniciar() throw (Excepcion&) {
	try {
		switch (pthread_create(&this->thread, NULL, &correr_helper, this)) {
			case EAGAIN:
				throw Excepcion("Insufficient resources to create another"
						" thread, or a system-imposed limit on the number of"
						" threads was encountered.  The latter case may occur"
						" in two ways: the RLIMIT_NPROC soft resource limit"
						" (set via setrlimit(2)), which limits the number of"
						" process for a real user ID, was reached; or the"
						" kernel's system-wide limit on the number ofthreads,"
						" /proc/sys/kernel/threads-max, was reached.");

			case EINVAL:
				throw Excepcion("Invalid settings in attr.");

			case EPERM:
				throw Excepcion("No permission to set the scheduling policy"
						" and parameters specified in attr.");
		}
	}
	catch (Excepcion& pEx) {
		pEx.expandirMensaje("Fallo al iniciar el thread.");
		throw pEx;
	}
}

void Thread::Finalizar() throw (Excepcion&) {
	try {
		switch (pthread_join(this->thread, NULL)) {
			case EDEADLK:
				throw Excepcion("A deadlock was detected (e.g., two threads"
						" tried to join with each other); or thread specifies"
						" the calling thread.");
				
			case EINVAL:
				throw Excepcion("thread is not a joinable thread or Another"
						" thread is already waiting to join with this thread.");

			case ESRCH:
				throw Excepcion("No thread with the ID thread could be found.");
		}
	}
	catch (Excepcion& pEx) {
		pEx.expandirMensaje("Fallo al finalizar el thread.");
		throw;
	}
}

bool Thread::Trabajando() {
	return this->trabajando;
}

int Thread::ID() {
	return (int)this->thread;
}

void* Thread::correr(void* pArgs) {
	this->trabajando = true;
	this->tarea();
	this->trabajando = false;
	return NULL;
}

